package task.manager.model;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;

import android.app.Application;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.widget.EditText;

// TODO: Auto-generated Javadoc
/**
 * The Class TaskApplication.
 */
@SuppressWarnings("unused")
public class TaskApplication extends Application {
	
	/** our actual back end class. */
	private UserManager theManager;
	
	/** support for the singleton design pattern. */
	private static TaskApplication INSTANCE;

	/** The current user. */
	private User currentUser;

	/** The task list. */
	private LinkedList<Task> taskList;

	/**
	 * Gets the single instance of TaskApplication.
	 *
	 * @return the singleton instance of the application object
	 */
	public static TaskApplication getInstance() {
		Log.d("APPLICATION", "Getting the singleton instance");
		return INSTANCE;
	}

	/* (non-Javadoc)
	 * @see android.app.Application#onCreate()
	 */
	@Override
	public void onCreate() {
		super.onCreate();
		Log.d("APPLICATION", "Setting up the application object");
		INSTANCE = this;
		theManager = new UserManager();
		Log.d("APPLICATION", "New User Manager was made");
	}

	/**
	 * Normally not used, use the facade methods instead.
	 *
	 * @return the instance of the actual back-end model
	 */
	public UserManager getUserManager() {
		Log.d("APPLICATION", "Getting the student manager object");
		return theManager;
	}
	
	/**
	 * Sets the user manager.
	 *
	 * @param user the new user manager
	 */
	public void setUserManager(UserManager user){
		theManager = user;
	}

	/**
	 * Load the application data from a serialized binary file.
	 *
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public void loadBinary() throws IOException {
		try {
			FileInputStream fis = openFileInput("data.bin");
			ObjectInputStream ois = new ObjectInputStream(fis);
			theManager = (UserManager) ois.readObject();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Save our application state as a binary file using java serialization.
	 *
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public void saveBinary() throws IOException {
		FileOutputStream fos;
		try {
			fos = openFileOutput("data.bin", Context.MODE_PRIVATE);
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(theManager);
			oos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Add a student to the application.
	 *
	 * @param name the name of the student to add
	 * @param username the username
	 * @param password the password
	 * @param email the email
	 */
	public void addUser(String name, String username, String password,
			String email) {
		User user = new User(name, username, password, email);
		theManager.addUser(user);
		currentUser = user;
		try {
			saveBinary();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Check login.
	 *
	 * @param id the id
	 * @param password the password
	 * @return true, if successful
	 */
	public boolean checkLogin(String id, String password) {
		LinkedList<User> users = theManager.getUsers();
		Iterator<User> it = users.iterator();
		boolean success = false;
		while (it.hasNext()) {
			User user = it.next();
			if (id.equals(user.getUsername())) {
				if (password.equals(user.getPassword())) {
					success = true;
					currentUser = user;
					taskList = getTaskList();
					break;
				}
			}
		}
		return success;
	}

	/**
	 * Gets the current user.
	 *
	 * @return the current user
	 */
	public User getCurrentUser() {
		return currentUser;
	}
	
	/**
	 * Sets the current user.
	 *
	 * @param user the new current user
	 */
	public void setCurrentUser(User user) {
		currentUser = user;
	}

	/**
	 * Gets the task list.
	 *
	 * @return the task list
	 */
	public LinkedList<Task> getTaskList() {
		return currentUser.getTaskList();
	}
	
	/**
	 * Sets the task list.
	 *
	 * @param list the new task list
	 */
	public void setTaskList(LinkedList<Task> list) {
		taskList = list;
	}
	
	/**
	 * Filter.
	 *
	 * @param category the category
	 * @param completed the completed
	 * @param date the date
	 * @return the linked list
	 */
	public LinkedList<Task> filter(String category, String completed, Date date) {
		LinkedList<Task> filtered = new LinkedList<Task>();

		Iterator<Task> it = getTaskList().iterator();
		int index = 0;
		while (it.hasNext()) {
			Task curr = it.next();		
			if ((category.equals("All") || curr.getCategory().equals(category))
					&& (completed.equals("All") || (completed.equals("In Progress") && !curr.getCompleted()) || (completed.equals("Completed") && curr.getCompleted()))
					&& (date == null || curr.getDate().compareTo(date) >= 0)) {
				curr.setIndex(index);
				filtered.add(curr);
			}
			index += 1;
		}
		
		return filtered;
	}
	
	
	/**
	 * Clear all users.
	 */
	public void clearAllUsers(){
		theManager = new UserManager();
	}
}
